package com.tourism.service.impl;

import cn.hutool.captcha.CaptchaUtil;
import cn.hutool.captcha.LineCaptcha;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.tourism.domain.dto.auth.AccountLoginDTO;
import com.tourism.core.security.entity.LoginUser;
import com.tourism.domain.entity.User;
import com.tourism.core.common.exception.CustomException;
import com.tourism.service.AuthService;
import com.tourism.service.UserService;
import com.tourism.core.common.utils.JwtUtils;
import com.tourism.core.common.utils.ResultCodeEnum;
import com.tourism.core.security.util.SecurityHolderUtils;
import com.tourism.core.common.utils.WebUtils;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.stereotype.Service;

import java.util.HashMap;
import java.util.Map;

/**
 * @author wb
 * @since 2025-10-07
 */

@Service
public class AuthServiceImpl implements AuthService {

    @Autowired
    private AuthenticationManager authenticationManager;

    @Autowired
    private UserService userService;

    @Override
    public Map<String, String> login(AccountLoginDTO accountLoginDTO) {
        // 验证验证码
        validateCaptcha(accountLoginDTO.getCaptchaKey(), accountLoginDTO.getCaptcha());
        try {

            // 构建用户名密码认证令牌
            UsernamePasswordAuthenticationToken usernamePassword = new UsernamePasswordAuthenticationToken(accountLoginDTO.getUsername(), accountLoginDTO.getPassword());

            // 对认证令牌进行认证
            Authentication authenticate = authenticationManager.authenticate(usernamePassword);

            // 获取认证后的用户详细信息
            LoginUser login = (LoginUser) authenticate.getPrincipal();

            // 当前登录用户
            User currentUser = login.getUser();

            // 生成token
            Map<String, String> claimMap = new HashMap<>();
            claimMap.put("id", currentUser.getId().toString());

            // 根据用户信息创建JWT Token
            String token = JwtUtils.createToken(claimMap);

            // 存储用户信息到session中
            WebUtils.getRequest().getSession().setAttribute("login_user:" + token, login);

            // 返回结果
            Map<String, String> result = new HashMap<>();
            result.put("token", token);


            return result;
        } catch (Exception e) {
            throw new CustomException(ResultCodeEnum.USERNAME_PASSWORD_ERROR);
        }
    }

    @Override
    public Boolean register(User user) {
        LambdaQueryWrapper<User> lqw = new LambdaQueryWrapper<User>().eq(User::getUsername, user.getUsername());
        User u = userService.getOne(lqw);
        if (u != null) {
            throw new CustomException("账号已存在");
        }
        return userService.save(user);
    }

    @Override
    public String generateCaptcha(String randomStr) {
        // 定义图形验证码的长和宽
        LineCaptcha lineCaptcha = CaptchaUtil.createLineCaptcha(100, 40, 5, 100);

        // 验证码值
        String code = lineCaptcha.getCode();

        WebUtils.getRequest().getSession().setAttribute("captcha:" + randomStr, code);

        // 验证码以base64的格式返回到客户端
        return lineCaptcha.getImageBase64Data();
    }

    @Override
    public User getInfo() {
        User user = SecurityHolderUtils.getLoginUser().getUser();
        if (user == null) {
            throw new CustomException(ResultCodeEnum.AUTH_NOT_LOGIN);
        }

        return user;
    }

    @Override
    public Boolean logout(String token) {
        HttpServletRequest request = WebUtils.getRequest();
        HttpSession session = request.getSession();
        session.setAttribute("login_user:" + token, null);
        session.invalidate();
        return true;
    }

    /**
     * 验证验证码
     *
     * @param randomStr 随机字符串
     * @param captcha 验证码
     */
    private void validateCaptcha(String randomStr, String captcha) {
        HttpSession session = WebUtils.getRequest().getSession();
        String code = (String) session.getAttribute("captcha:" + randomStr);

        if (code == null) {
            throw new CustomException(ResultCodeEnum.CAPTCHA_NOT_EXIST);
        }
        if (!code.equalsIgnoreCase(captcha)) {
            throw new CustomException(ResultCodeEnum.CAPTCHA_ERROR);
        }

        session.setAttribute("captcha:" + randomStr, null);
    }
}
